#include "iConfig.hpp"

#include <glf/io/stream.h>

//known 'streams'
/*
	win32 FILE*
	 
	rvl FILE* on ndev, can open windows file
	rvl Dvd files
	rvl Cnt files
	rvl Nand files
	rvl archd files
*/


namespace glf {

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------


Stream::Stream() :
	mLastError(fs::ERROR_NONE),
	mIsOpened(false),
	mIsBusy(false),
	mCallbackResult(0),
	mCallback(0),
	mCallbackArg(0)
{

}

Stream::~Stream() {
}

fs::Error Stream::GetLastError() const {
	return mLastError;
}

size_t Stream::Read(void* buffer, size_t size) {
	return 0;
}

size_t Stream::ReadWithOffset(void* buffer, size_t size, size_t offset) {
	return 0;
}

bool Stream::ReadASync(void* buffer, size_t size, size_t offset, Callback callback, void* arg) {
	return false;
}

size_t Stream::Write(const void* buffer, size_t size) { 
	return 0;
}
//
//bool Stream::WriteASync(const void* buffer, size_t size, Callback callback, void* arg)
//{
//	return false;
//}


size_t Stream::GetOffsetAlign() const {
	return 1;
}

size_t Stream::GetSizeAlign() const {
	return 1;
}

size_t Stream::GetBufferAlign() const {
	return 1;
}


bool Stream::IsOpened() const {
	return mIsOpened;
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------

IOStream::IOStream() :
	Stream()
{ 
}

bool IOStream::Seek( int offset, seek origin ) {
	//GLFi_ASSERTMSG( CanSeek(), "Stream don't support SEEK function\n" );
	return false;
}

size_t IOStream::Peek(void* buffer, size_t size) {
	return 0;
}

//void IOStream::Cancel( void )
//{
//    //GLFi_ASSERTMSG( CanCancel(), "Stream don't support CANCEL function\n" );
//}

//bool IOStream::CancelASync( Callback callback, void* arg ) {
//    //GLFi_ASSERTMSG( CanCancel(), "Stream don't support CANCEL function\n" );
//    //GLFi_ASSERTMSG( CanAsync(),  "Stream don't support ASYNC function\n" );
//    return true;
//}

bool Stream::IsBusy() const {
	return mIsBusy;
}

int Stream::WaitASync(size_t ms) const {
	while(mIsBusy) {
		glf::Thread::Sleep(1);
	}
	return mCallbackResult;
}

bool IOStream::IsEof() const { 
	return Tell() >= GetSize();  
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------

IOStream::FilePosition::FilePosition() : 
	mSize(0), 
	mPosition(0) 
{

}

void IOStream::FilePosition::SetFileSize( size_t fileSize ) { 
	mSize = fileSize; 
}

size_t IOStream::FilePosition::GetFileSize() const { 
	return mSize; 
}

size_t IOStream::FilePosition::Skip( int offset ) {
    if ( offset != 0 ) {
        mPosition += static_cast<size_t>(offset);
    }
    return mPosition;
}

size_t IOStream::FilePosition::Append(int offset) {
    int64 position = mPosition + offset;
    
    if(position < 0)
    {
        mPosition = 0;
    }
    else
    {
        mPosition = static_cast<size_t>(position);
        mSize = Max( mPosition, mSize );
    }
    
	return mPosition;
}

bool IOStream::FilePosition::Seek( int offset, seek origin ) {
	if(origin == beg) {
		mPosition = 0;
	} else if(origin == end) {
		mPosition = mSize;
	}

	Skip( offset );

	return true;
}

size_t IOStream::FilePosition::Tell() const { 
	return mPosition; 
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------

} //namespace glf

